<template>
  <div class="all-select">
    <el-popover
      placement="bottom-start"
      :width="width"
      trigger="click"
      popper-class="allPopover"
    >
      <div class="checkbox-content">
        <div class="checkbox-content-filter">
          <el-input
            v-model="keyWord"
            placeholder="输入关键字"
            @input="onSearch"
            style="margin-bottom: 10px"
          ></el-input>
          <el-radio-group
            v-model="radio"
            @input="CheckChange"
            class="radio-group"
          >
            <el-radio label="checkAll">全选</el-radio>
            <el-radio label="clearAll">全不选</el-radio>
            <el-button round size="mini" @click="handleReverse">反选</el-button>
          </el-radio-group>
        </div>
        <el-empty v-if="options.length == 0" description="暂无数据"></el-empty>
        <el-checkbox-group
          v-else
          v-model="checked"
          @change="handleCheckedCitiesChange"
          class="checkbox-group"
        >
          <el-checkbox
            v-for="checkbox in checkboxs"
            :label="checkbox[code]"
            :key="checkbox[code]"
            class="checkbox-group-item"
            :disabled="checkbox.disabled"
          >
            {{ checkbox[label] }}
          </el-checkbox>
        </el-checkbox-group>
      </div>
      <div
        slot="reference"
        class="reference"
        :style="{ width: width - 40 + 'px' }"
        :data-attr="attr"
      >
        <span
          class="selectItem"
          v-for="(item, index) in selectItems.slice(0, limit)"
          :key="index"
        >
          <span class="item-name">{{ item[label] }}</span>
          <!-- <i class="itemclear el-icon-error" @click.stop="clearItem(item)"></i> -->
          <i class="itemclear el-icon-close" @click.stop="clearItem(item)"></i>
        </span>
        <span class="itemMore" v-show="selectItems.length > limit">
          +{{ selectItems.length - limit }}
        </span>
        <i
          v-show="clearShow"
          class="reference-clear el-icon-close"
          @click.stop="clearAll"
          @mouseleave="clearShow = false"
        ></i>
        <i
          v-show="!clearShow"
          @mouseenter="clearShow = true"
          class="reference-select el-icon-arrow-down"
        ></i>
      </div>
    </el-popover>
  </div>
</template>
<script>
export default {
  name: "AllSelect",
  props: {
    placeholder: {
      type: String,
      default: "",
    },
    value: null,
    limit: {
      type: Number,
      default: 2,
    },
    options: {
      type: Array,
      default: () => {
        return [];
      },
    },
    "select-options": {
      type: Object,
      default: () => {
        return {
          value: "id",
          label: "name",
        };
      },
    },
    width: {
      type: [Number, String],
      default: "350",
    },
  },
  data() {
    return {
      clearShow: false,
      keyWord: "",
      selectItems: [],
      //
      radio: null,
      checked: [],
      checkboxs: [],
      attr: this.placeholder,
    };
  },
  computed: {
    code() {
      return this.selectOptions.value;
    },
    label() {
      return this.selectOptions.label;
    },
    valueType() {
      if (Array.isArray(this.value)) {
        return "arr";
      } else {
        return "str";
      }
    },
  },
  watch: {
    options: {
      handler(val) {
        this.checkboxs = val;
      },
      immediate: true,
    },
    checked(val) {
      this.selectItems =
        val?.map((v) => this.checkboxs.find((item) => item[this.code] === v)) ??
        [];
      if (val.length == 0) {
        this.radio = "clearAll";
      } else {
        if (val.length === this.options.length) {
          this.radio = "checkAll";
        } else {
          this.radio = null;
        }
      }
      this.$emit("update:value", this.valueType == "arr" ? val : val.join());
    },
    value: {
      handler(val) {
        if (!val) {
          this.attr = this.placeholder;
          this.checked = [];
          return;
        }
        this.attr = "";
        if (Array.isArray(val)) {
          this.checked = val;
        } else {
          this.checked = val.split(",");
        }
      },
      immediate: true,
    },
  },
  methods: {
    onSearch(val) {
      this.checked = [];
      if (val == "") {
        this.checkboxs = this.options;
      } else {
        this.checkboxs = this.checkboxs.filter((item) => {
          return item[this.label].includes(val);
        });
      }
    },
    CheckChange(val) {
      if (val == "checkAll") {
        this.checked = this.checkboxs.map((item) => item[this.code]);
      } else if (val == "clearAll") {
        this.checked = [];
      }
      this.$emit("change", this.checked);
    },
    handleReverse(val) {
      const nochecked = this.checkboxs.filter((item) => {
        return !this.checked.includes(item[this.code]);
      });
      if (nochecked.length == 0) {
        this.radio = "clearAll";
      } else {
        if (nochecked.length === this.checkboxs.length) {
          this.radio = "checkAll";
        } else {
          this.radio = null;
        }
      }
      this.checked = nochecked.map((item) => item[this.code]);
    },
    handleCheckedCitiesChange(value) {
      let checkedCount = value.length;
      if (checkedCount == 0) {
        this.radio = "clearAll";
      } else {
        if (checkedCount === this.checkboxs.length) {
          this.radio = "checkAll";
        } else {
          this.radio = null;
        }
      }
      this.$emit("change", value);
    },
    clearItem(item) {
      const id = item[this.code];
      this.checked = this.checked.filter((item) => item !== id);
    },
    clearAll() {
      this.radio = null;
      this.checked = [];
    },
  },
};
</script>
<style lang="scss">
.allPopover {
  margin-top: 6px !important;
}
</style>
<style scoped lang="scss">
::-webkit-scrollbar {
  height: 0px !important;
  width: 0px !important;
}
.selectItem {
  background-color: #f4f4f5;
  border-color: #e9e9eb;
  color: #909399;
  display: flex;
  align-items: center;
  padding: 0 3px;
  line-height: 19px;
  font-size: 12px;
  border-radius: 4px;
  border: 1px solid #e9e9eb;
  .item-name {
    max-width: 60px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .itemclear {
    cursor: pointer;
    border-radius: 50%;
    background-color: #c0c4cc;
    font-size: 12px;
    height: 16px;
    width: 16px;
    line-height: 16px;
    text-align: center;
    transform: scale(0.7);
    &:hover {
      color: #ffffff;
      background-color: #909399;
    }
  }
}
.itemMore {
  background-color: #f4f4f5;
  border-color: #e9e9eb;
  color: #909399;
  height: 24px;
  padding: 0 6px;
  line-height: 22px;
  font-size: 12px;
  border-radius: 4px;
}

.checkbox-content {
  height: 100%;
  position: relative;
  max-height: 470px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  .checkbox-content-filter {
    background-color: #ffffff;
    position: sticky;
    top: 0;
    z-index: 9999;
    margin-right: 12px;
    .radio-group {
      ::v-deep {
        .el-radio {
          margin-right: 12px;
        }
      }
    }
  }
  .checkbox-group {
    display: flex;
    flex-direction: column;
    overflow: auto;
    .checkbox-group-item {
      margin: 6px 0;
    }
  }
}
.all-select {
  ::v-deep {
    .reference {
      height: 30px;
      line-height: 30px;
      border: 1px solid #dcdfe6;
      border-radius: 6px;
      position: relative;
      padding: 0 40px 0 0;
      display: flex;
      align-items: center;
      overflow: auto;
      gap: 6px;
      box-sizing: content-box;
      min-width: 220px;
      cursor: pointer;
      &::before {
        content: attr(data-attr);
        color: #ccc;
        transform: translate(10px);
      }
      .reference-select {
        position: absolute;
        right: 12px;
        line-height: 30px;
        cursor: pointer;
      }
      .reference-clear {
        position: absolute;
        right: 9px;
        line-height: 30px;
        color: #c0c4cc;
        border: 1px solid #c0c4cc;
        border-radius: 50%;
        font-size: 12px;
        height: 16px;
        width: 16px;
        line-height: 16px;
        text-align: center;
        transform: scale(0.7);
        cursor: pointer;
      }
    }
  }
}
</style>
